from utils import DUtils
import socket, sys, threading

class Client:
    def __init__(self, uid) -> None:
        self.uid: int = uid

    def new(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect(("0.0.0.0", 44000))

    def login(self, pwd):
        self.new()
        self.sock.sendall(DUtils.login_session(self.uid, pwd))
        size = int.from_bytes(self.sock.recv(2), 'big')
        lpack = DUtils.parse_login_c(self.sock.recv(size))
        if type(lpack) == str:
            print("login failed", lpack)
        print("login successfully", lpack)
        self.recv_thread = threading.Thread(target=self.recv_message, daemon=True)
        self.recv_thread.start()
        try:
            self.send_message()
        except KeyboardInterrupt:
            self.sock.sendall(DUtils.logout_session(self.uid))
            self.sock.close()
    
    def register(self, pwd):
        self.new()
        self.sock.sendall(DUtils.register_session(self.uid, pwd))
        rpack = DUtils.parse_register_c(self.recv())
        if type(rpack) == str:
            print("register failed", rpack)
        else:
            print("register successfully", rpack)
        self.sock.close()
        self.login(pwd)
    
    def send_message(self):
        while True:
            s = sys.stdin.readline().split(' ')
            uid = s[0]
            text = " ".join(s[1:])
            self.sock.sendall(DUtils.message_session(text, 0, uid=int(uid)))

    def recv(self):
        return self.sock.recv(int.from_bytes(self.sock.recv(2), 'big'))
    
    def recv_message(self):
        while True:
            pack = DUtils.parse_message(self.recv())
            if pack is None:continue
            func, id, text, = pack
            if func == 0x00:
                sys.stdout.write(f"[Pri] <{id}> {text}")
                sys.stdout.flush()
            else:
                sys.stdout.write(f"[Pub] <{id}> {text}")
                sys.stdout.flush()

client = Client(10002)
client.login('12345')